package qg.fangrui.springboot.service;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.session.SessionProperties.Redis;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import qg.fangrui.springboot.dao.UserDao;
import qg.fangrui.springboot.exception.CacheException;
import qg.fangrui.springboot.model.User;

/**
 * User Service
 * Created by zggdczfr on 2017/2/28.
 */
@CacheConfig(cacheNames = "users")
@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RedisTemplate redisTemplate;
    
    //添加到数据库的同时加入缓存
    @CachePut(key = "'user_'+#user.getUuid()")
    public int save(User user) throws Exception {
    	//執行新增是更新緩存，比如更新緩存的list集合
    	System.out.println("11");
    	if(redisTemplate.hasKey("qg.fangrui.springboot.service.UserServicefindByAge15")){
    		System.out.println("刪除緩存的集合");
    		redisTemplate.delete("qg.fangrui.springboot.service.UserServicefindByAge15");
    	}
    	
        return userDao.save(user);
    }
    //使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果，而是每次都会执行该方法，并将执行结果以键值对的形式存入指定的缓存中。
   // @CachePut(value = "usercache",keyGenerator = "wiselyKeyGenerator")
    @CachePut(key = "'user_'+#user.getUuid()")
    public User update(User user) throws CacheException{
        User user1 = userDao.findByUuid(user.getUuid());
        if (null == user1){
            throw new  CacheException("Not Find");
        }
        user1.setAge(user.getAge());
        user1.setName(user.getName());
        userDao.update(user1);
        return user1;
    }

    // Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素，如果存在就不再执行该方法，而是直接从缓存中获取结果进行返回，否则才会执行并将返回结果存入指定的缓存中。
   // @Cacheable(value = "usercache",keyGenerator = "wiselyKeyGenerator"),
    //可以使用主键生成器来生成key,一般使用包名+类名+方法名，但是会导致一个方法查出的结果只有一个key,不断覆盖这一条数据
    @Cacheable(key="'user_'+#uuid")
    public User findByUuid(String uuid){
    	
        User user = userDao.findByUuid(uuid);
      
        System.out.println("没有走缓存");
        return user;
    }

   // @CacheEvict(value = "usercache",keyGenerator = "wiselyKeyGenerator")//这是清除缓存
    @CacheEvict(key="'user_'+#uuid")
    public void delete(String uuid){
        userDao.delete(uuid);
    }
    
    
    
    //关于集合的缓存可以设置缓存超时，定时更新缓存等一系列缓存策略来达到我们的要求（一般缓存不经常发生改变的数据）
    //我們也可以在數據發生改變時，就清除這個緩存，如上面的save方法
    //不要忘记设置缓存时间
   @SuppressWarnings("unchecked")
@Cacheable(value = "usercache",keyGenerator = "wiselyKeyGenerator") 
	public List<User> findByAge(Integer age){
    	
        List<User> userlist = userDao.findByAge(age);
        
        //设置key的缓存时间，如果用set写入时，需要更新超时时间，不然会失效，也可以使用RedisConfig中的CacheManager来配置全局缓存时间
       /* 例如：
        int tempTime = this.redisTemplate.getExpire("max").intValue();
        tempCount = this.redisTemplate.opsForValue().get("max")-1;
        this.redisTemplate.opsForValue().set("max", tempCount);
        this.redisTemplate.expire("max",tempTime,TimeUnit.SECONDS);*/
        
        this.redisTemplate.expire("qg.fangrui.springboot.service.UserServicefindByAge15",1000,TimeUnit.SECONDS);
       /* 
        if(redisTemplate.hasKey("listkey1")){
            System.out.println("走缓存");

        	return (List<User>) redisTemplate.opsForList().leftPop("listkey1"); 

        }
        
        
        redisTemplate.opsForList().leftPush("listkey1",userlist);  
        */
        System.out.println("没有走缓存");
        return userlist;
    }
    
    public void test(){
    	 
    	
    	
    }
    
}
